//
//  IKDownloadTool.m
//  IKFoundation
//
//  Created by Chenxiaocheng on 16/7/20.
//  Copyright © 2016年 inke. All rights reserved.
//

#import "IKDownloader.h"
#import "FCBasics.h"
#import <AFNetworking/AFHTTPSessionManager.h>


@class IKDownloadTask;

typedef void(^IKDownloadProgress)(IKDownloadTask *task, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile);

typedef void (^IKDownloadSucces)(IKDownloadTask *task, id responseObject);

typedef void (^IKDownloadFailure)(IKDownloadTask *task, NSError *error);

@implementation IKDownloadItem

@end

@implementation IKDownloadInfo

@end

@interface IKDownloadTask : NSObject {
    AFHTTPSessionManager *_manager;
}

@property(nonatomic, strong) IKDownloadItem *item;
@property(nonatomic, strong) NSURLSessionDownloadTask *downloadTask;

- (void)addTask:(IKDownloadItem *)item progress:(IKDownloadProgress)progress success:(IKDownloadSucces)success failure:(IKDownloadFailure)failure;

- (void)cancel;

@end

@implementation IKDownloadTask

- (void)addTask:(IKDownloadItem *)item progress:(IKDownloadProgress)progress success:(IKDownloadSucces)success failure:(IKDownloadFailure)failure
{
    self.item = item;
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:item.url]];
    _manager = [AFHTTPSessionManager manager];
    typeof(self) __weak weakSelf = self;
    _downloadTask = [_manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        typeof(self) __strong strongSelf = weakSelf;
        if (!strongSelf) {
            return;
        }
        if (progress) {
            progress(strongSelf, downloadProgress.completedUnitCount, downloadProgress.totalUnitCount);
        }
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        typeof(self) __strong strongSelf = weakSelf;
        if (!strongSelf) {
            return nil;
        }
        return [NSURL fileURLWithPath:item.filePath];
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        typeof(self) __strong strongSelf = weakSelf;
        if (error) {
            if (failure) {
                failure(strongSelf, error);
            }
        } else {
            if (success) {
                success(strongSelf, nil); // responseObject
            }
        }
    }];
    [_downloadTask resume];
}

- (void)cancel {
    [_downloadTask cancel];
}

- (void)dealloc {
    NSLog(@"---- dealloc");
    _manager = nil;
}

@end;

@implementation IKDownloader {
    IKDownloadTask *_task;
    IKDownloadItem *_downloadItem;
}


- (instancetype)initWithItem:(IKDownloadItem *)item {
    _downloadItem  = item;
    return [self init];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _item = _downloadItem;
        _info = [IKDownloadInfo new];
    }
    return self;
}

- (void)start {
    if (!_item) {
        NSLog(@"invalid download item");
        return;
    }
    
    _task = [[IKDownloadTask alloc] init];
    
    __weak typeof(self) weakSelf = self;
    
    [_task addTask:_item progress:^(IKDownloadTask *task, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        
        if (!strongSelf) {
            return;
        }
        
        strongSelf.info.fileSize = totalBytesExpectedToReadForFile;
        strongSelf.info.downloadedSize = totalBytesReadForFile;
        
        if ([strongSelf.delegate respondsToSelector:(@selector(Downloader:progress:total:))]) {
            [strongSelf.delegate Downloader:strongSelf progress:totalBytesReadForFile total:totalBytesExpectedToReadForFile];
        }
        
    } success:^(IKDownloadTask *task, id responseObject) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) {
            return;
        }
        
        if ([strongSelf.delegate respondsToSelector:(@selector(Downloader:code:))]) {
            [strongSelf.delegate Downloader:strongSelf code:0];
        }
        
    } failure:^(IKDownloadTask *task, NSError *error) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (!strongSelf) {
            return;
        }
        
        if ([strongSelf.delegate respondsToSelector:(@selector(Downloader:code:))]) {
            NSInteger code = error ? error.code : -1;
            if (code == 0) {
                code = -1;
            }
            
            [strongSelf.delegate Downloader:strongSelf code:code];
        }
    }];
}

- (void)cancel {
    [_task cancel];
}

- (float)progress {
    if (_info.fileSize == 0) {
        return 0;
    } else {
        return _info.downloadedSize / (float)_info.fileSize;
    }
}

@end

